package org.abc.fund.service.factorService;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PythonScriptService {

    private static final String DEFAULT_BASE_URL = "http://localhost:8000";
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    public static class FundRequest {
        private String code;
        @JsonProperty("start_date")
        private String startDate;
        @JsonProperty("end_date")
        private String endDate;
        private Integer per;

        public FundRequest() {}

        public FundRequest(String code, String startDate, String endDate, Integer per) {
            this.code = code;
            this.startDate = startDate;
            this.endDate = endDate;
            this.per = per;
        }

        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getStartDate() { return startDate; }
        public void setStartDate(String startDate) { this.startDate = startDate; }
        public String getEndDate() { return endDate; }
        public void setEndDate(String endDate) { this.endDate = endDate; }
        public Integer getPer() { return per; }
        public void setPer(Integer per) { this.per = per; }
    }

    public static class FundResponse {
        private boolean success;
        private String message;
        private List<Map<String, Object>> data;
        @JsonProperty("total_records")
        private Integer totalRecords;

        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public List<Map<String, Object>> getData() { return data; }
        public void setData(List<Map<String, Object>> data) { this.data = data; }
        public Integer getTotalRecords() { return totalRecords; }
        public void setTotalRecords(Integer totalRecords) { this.totalRecords = totalRecords; }
    }

    public static FundResponse getFundHistory(String code, String startDate, String endDate,
                                              Integer per, String baseUrl) throws IOException {
        if (baseUrl == null || baseUrl.trim().isEmpty()) {
            baseUrl = DEFAULT_BASE_URL;
        }

        FundRequest request = new FundRequest(code, startDate, endDate, per);
        String requestBody = objectMapper.writeValueAsString(request);

        HttpRequest httpRequest = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/fund/history"))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                .timeout(Duration.ofSeconds(30))
                .build();

        try {
            HttpResponse<String> response = httpClient.send(httpRequest,
                    HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() == 200) {
                return objectMapper.readValue(response.body(), FundResponse.class);
            } else {
                throw new IOException("HTTP请求失败，状态码: " + response.statusCode() +
                        ", 响应: " + response.body());
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("请求被中断", e);
        }
    }

    public static FundResponse getFundHistory(String code, String startDate, String endDate,
                                              Integer per) throws IOException {
        return getFundHistory(code, startDate, endDate, per, null);
    }

    public static FundResponse getFundHistory(String code, String startDate, String endDate)
            throws IOException {
        return getFundHistory(code, startDate, endDate, 40, null);
    }

    public static boolean checkHealth(String baseUrl) {
        if (baseUrl == null || baseUrl.trim().isEmpty()) {
            baseUrl = DEFAULT_BASE_URL;
        }

        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl + "/health"))
                    .GET()
                    .timeout(Duration.ofSeconds(5))
                    .build();

            HttpResponse<String> response = httpClient.send(request,
                    HttpResponse.BodyHandlers.ofString());

            return response.statusCode() == 200;
        } catch (Exception e) {
            System.err.println("健康检查失败: " + e.getMessage());
            return false;
        }
    }

    public static boolean checkHealth() {
        return checkHealth(null);
    }

    public static void main(String[] args) {
        System.out.println("=== 基金净值查询工具测试 ===");

        System.out.println("1. 检查服务健康状态...");
        boolean isHealthy = checkHealth();
        System.out.println("服务状态: " + (isHealthy ? "正常" : "异常"));

        if (!isHealthy) {
            System.out.println("请确保FastAPI服务已启动 (python main.py)");
            return;
        }

        System.out.println("\n2. 测试基金净值查询...");
        String fundCode = "000001";
        String startDate = "2020-01-01";
        String endDate = "2020-03-01";

        try {
            System.out.println("查询参数:");
            System.out.println("基金代码: " + fundCode);
            System.out.println("开始日期: " + startDate);
            System.out.println("结束日期: " + endDate);

            FundResponse response = getFundHistory(fundCode, startDate, endDate);

            System.out.println("\n查询结果:");
            System.out.println("成功: " + response.isSuccess());
            System.out.println("消息: " + response.getMessage());
            System.out.println("总记录数: " + response.getTotalRecords());

            if (response.isSuccess() && response.getData() != null && !response.getData().isEmpty()) {
                System.out.println("\n前5条数据:");
                int count = Math.min(5, response.getData().size());
                for (int i = 0; i < count; i++) {
                    Map<String, Object> record = response.getData().get(i);
                    System.out.println((i + 1) + ". 日期: " + record.get("date") +
                            ", 单位净值: " + record.get("unit_nav") +
                            ", 累计净值: " + record.get("accumulated_nav") +
                            ", 日增长率: " + record.get("daily_growth"));
                }

                if (response.getData().size() > 5) {
                    System.out.println("... 还有 " + (response.getData().size() - 5) + " 条记录");
                }
            }

        } catch (IOException e) {
            System.err.println("查询失败: " + e.getMessage());
            e.printStackTrace();
        }

        System.out.println("\n=== 测试完成 ===");
    }

    public Map<String, Object> executeScript(String code) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 写入临时文件
            File tempFile = File.createTempFile("script", ".py");
            try (FileWriter writer = new FileWriter(tempFile)) {
                writer.write(code);
            }
            // 执行python
            ProcessBuilder pb = new ProcessBuilder("python", tempFile.getAbsolutePath());
            pb.redirectErrorStream(true);
            
            // Set environment variables to ensure UTF-8 encoding for Python output
            pb.environment().put("PYTHONIOENCODING", "UTF-8");
            pb.environment().put("PYTHONUTF8", "1");
            
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
            StringBuilder output = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line);
            }
            int exitCode = process.waitFor();
            result.put("success", exitCode == 0);
            result.put("output", output.toString());
            result.put("message", exitCode == 0 ? "执行成功" : "执行失败");
        } catch (Exception e) {
            result.put("success", false);
            result.put("output", "");
            result.put("message", "执行异常: " + e.getMessage());
        }
        return result;
    }
}